{/* Copyright 2020 Adobe. All rights reserved.
This file is licensed to you under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. You may obtain a copy
of the License at http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under
the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
OF ANY KIND, either express or implied. See the License for the specific language
governing permissions and limitations under the License. */}

import {Layout} from '@react-spectrum/docs';
export default Layout;

import ChevronRight from '@spectrum-icons/workflow/ChevronRight';
import styles from '@react-spectrum/docs/src/docs.css';

---
category: Introduction
type: hook
navigationTitle: Getting Started
---

# React Aria Hooks

This page describes how to get started with React Aria hooks.

## Installation

React Aria can be installed using a package manager like [npm](https://docs.npmjs.com/cli/npm) or
[yarn](https://classic.yarnpkg.com/lang/en/).

```
yarn add react-aria
```

If you prefer, you can also use our hooks from individually versioned packages. This allows you to only
install the hooks you use, or more granularly manage their versions. The individual packages are published
under the [@react-aria](https://www.npmjs.com/org/react-aria) scope on npm. For example:

```
yarn add @react-aria/button
```

Once installed, hooks can be used from the monopackage or individual packages the same way.

```tsx
// Monopackage
import {useButton} from 'react-aria';
```

```tsx keepIndividualImports
// Individual packages
import {useButton} from '@react-aria/button';
```

## Building a component

React Aria provides behavior and accessibility through React Hooks. Since it does not provide any rendering,
you are responsible for defining the DOM structure for your component and passing the DOM props returned by each
React Aria hook to the appropriate elements. This is powerful because it allows you to be in complete control over
the DOM structure that you render. For example, you may need to add extra elements for styling or layout control.
You also get complete control over how you style your components: you could use CSS classes, inline styles, CSS-in-JS, etc.

Start by importing the hook you wish to use, and calling it in your component. You'll typically pass through the props
from your component, along with a [ref](https://react.dev/learn/referencing-values-with-refs#refs-and-the-dom) to the DOM node in some cases.
The hook will return one or more sets of DOM props which you should pass through to the appropriate element. This can be
done by [spreading the props](https://react.dev/learn/passing-props-to-a-component#forwarding-props-with-the-jsx-spread-syntax) returned from the hook onto
the element that you render.

This example shows a very simple button component built with the [useButton](useButton.html) hook.

```tsx example export=true
import {useButton} from '@react-aria/button';

function Button(props) {
  /*- begin highlight -*/
  let ref = React.useRef(null);
  let {buttonProps, isPressed} = useButton(props, ref);
  /*- end highlight -*/

  return (
    <button
      /*- begin highlight -*/
      ref={ref}
      {...buttonProps}
      /*- end highlight -*/
      style={{
        background: isPressed ? '#444' : '#666',
        color: 'white',
        padding: '6px 12px',
        borderRadius: 4,
        border: 'none'
      }}>
      {props.children}
    </button>
  );
}

<Button onPress={() => alert('Button pressed!')}>
  Press me
</Button>
```

Now you just need to add your own styling, and you have a fully accessible button component that works consistently
across mouse, touch, keyboard, and screen readers with [high quality interactions](../blog/building-a-button-part-1)!
See the [useButton](useButton.html) docs more examples.

## Stateful components

Many components are **stateless** — they display information to a user. Examples of stateless components include buttons,
progress bars, and links. These components don't update as the user interacts with them.

A **stateful** component has some state, and allows a user to interact with the component in order to update that state.
Examples of stateful components include text fields, checkboxes, and selects.

React Aria separates the state management logic into a separate hook that lives in React Stately.
The state hook holds the state for the component, and provides an interface to read and update that state. This allows
this logic to be reused across different platforms, e.g. in react-native. Read more about this on the
[architecture](../architecture.html) page.

To build a stateful component, you'll need to install and import the corresponding state hook from react-stately.
Then, call the state hook from your component, and pass the resulting state object to the React Aria hook.
You can also use the state in your rendering code to determine what visual state to display.

This example shows a number field component built with the [useNumberField](useNumberField.html) hook, along
with the [useNumberFieldState](../react-stately/useNumberFieldState.html) hook from react-stately.

```tsx example
import {useNumberFieldState} from 'react-stately';
import {useLocale, useNumberField} from 'react-aria';

function NumberField(props) {
  let {locale} = useLocale();
  let state = useNumberFieldState({...props, locale});
  let inputRef = React.useRef(null);
  let {
    labelProps,
    groupProps,
    inputProps,
    incrementButtonProps,
    decrementButtonProps
  } = useNumberField(props, state, inputRef);

  return (
    <div>
      <label {...labelProps}>{props.label}</label>
      <div {...groupProps} style={{display: 'flex', gap: 4}}>
        <Button {...decrementButtonProps}>-</Button>
        <input {...inputProps} ref={inputRef} />
        <Button {...incrementButtonProps}>+</Button>
      </div>
    </div>
  );
}

<NumberField
  label="Price"
  defaultValue={6}
  formatOptions={{
    style: 'currency',
    currency: 'USD'
  }}
/>
```

This gives you a number field complete with input validation, internationalized formatting, accessibility,
mobile keyboard support, and much more! See the [useNumberField](useNumberField.html)
docs to learn more about all of the features.
